package megadrum.gui;

import java.util.*;
import javax.swing.*;
import java.io.Serializable;

public class CustomSpinnerListModel extends AbstractSpinnerModel implements Serializable, CustomSpinnerModel {

    protected List list;
    protected int index;

    public CustomSpinnerListModel(List<?> values) {
        if (values == null || values.size() == 0) {
            throw new IllegalArgumentException("SpinnerListModel(List) expects non-null non-empty List");
        }
        this.list = values;
        this.index = 0;
    }

    public CustomSpinnerListModel(Object[] values) {
        if (values == null || values.length == 0) {
            throw new IllegalArgumentException("SpinnerListModel(Object[]) expects non-null non-empty Object[]");
        }
        this.list = Arrays.asList(values);
        this.index = 0;
    }

    public CustomSpinnerListModel() {
        this(new Object[]{"empty"});
    }

    public List<?> getList() {
        return list;
    }

    public void setList(List<?> list) {
        if ((list == null) || (list.size() == 0)) {
            throw new IllegalArgumentException("invalid list");
        }
        if (!list.equals(this.list)) {
            this.list = list;
            index = 0;
            fireStateChanged();
        }
    }

    public Object getValue() {
        return list.get(index);
    }

    public int getIntValue() {
        return index;
    }

    public void setValue(Object elt) {
        int ind = list.indexOf(elt);
        if (ind == -1) {
            throw new IllegalArgumentException("invalid sequence element");
        } else if (ind != this.index) {
            this.index = ind;
            fireStateChanged();
        }
    }

    public void setIntValue(int index) {
        if (index == -1) {
            throw new IllegalArgumentException("invalid sequence element");
        } else if (index != this.index) {
            this.index = index;
            fireStateChanged();
        }
    }

    public int getCount() {
        return list.size();
    }

    public int getMinimum() {
        return 0;
    }

    public int getMaximum() {
        return list.size() - 1;
    }

    public Object getNextValue() {
        return (index >= (list.size() - 1)) ? null : list.get(index + 1);
    }

    public Object getPreviousValue() {
        return (index <= 0) ? null : list.get(index - 1);
    }

    
    Object findNextMatch(String substring) {
        int max = list.size();

        if (max == 0) {
            return null;
        }
        int counter = index;

        do {
            Object value = list.get(counter);
            String string = value.toString();

            if (string != null && string.startsWith(substring)) {
                return value;
            }
            counter = (counter + 1) % max;
        } while (counter != index);
        return null;
    }
}

